package com.laolei.core.logging;

import java.lang.reflect.Method;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;

import com.laolei.core.Context;
import com.laolei.core.utils.ClasseUtils;
import com.laolei.core.utils.MapUtils;

/**
 * Aop 访问日志
 * 
 * @author lenovo
 *
 */
@Aspect
@Order(1)
@Component
public class ControllerLogAop {

	@Around("within(@org.springframework.web.bind.annotation.RestController *)")
	public Object restRecordSysLog(ProceedingJoinPoint point) throws Throwable {
		Method method = ((MethodSignature) point.getSignature()).getMethod();
		Context.isRest(true);
		return recordSysLog(point, method);
	}

	@Around("within(@org.springframework.stereotype.Controller *)")
	public Object otherRecordSysLog(ProceedingJoinPoint point) throws Throwable {
		Method method = ((MethodSignature) point.getSignature()).getMethod();
		Context.isRest(ClasseUtils.hasAnnotation(method, ResponseBody.class));
		return recordSysLog(point, method);
	}

	public Object recordSysLog(ProceedingJoinPoint point, Method method) throws Throwable {
		String methodName = ClasseUtils.getMethodName(method);
		RunTimeLog.log("方法执行结束:{}", methodName);
		try {
			return point.proceed();
		} finally {
			HttpServletRequest request = Context.getRequest();
			Object params = getParamObject(request.getParameterMap());
			RunTimeLog.log("方法执行结束:{} ,[参数]:{}", methodName, params);
		}
	}

	private Object getParamObject(Map<String, ?> params) {
		return new Object() {
			@Override
			public String toString() {
				return MapUtils.n(params).array((k, v) -> {
					return k + "=" + v;
				}).join("&");
			};
		};
	}

}
